﻿using LightCAD.Core.Elements;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Xml.Linq;
using LightCAD.MathLib;

namespace LightCAD.Core
{
    public static class JsonWriterExt
    {
        public static void WriteIdProperty(this Utf8JsonWriter writer, string name, long value)
        {
            writer.WritePropertyName(name);
            writer.WriteNumberValue(value);
        }
        public static void WriteStringProperty(this Utf8JsonWriter writer, string name, string value)
        {
            writer.WritePropertyName(name);
            writer.WriteStringValue(value);
        }
        public static void WriteNumberProperty(this Utf8JsonWriter writer, string name, double value)
        {
            writer.WritePropertyName(name);
            writer.WriteNumberValue(value);
        }
        public static void WriteBoolProperty(this Utf8JsonWriter writer, string name, bool value)
        {
            writer.WritePropertyName(name);
            writer.WriteBooleanValue(value);
        }

        public static void WriteMatrix3dProperty(this Utf8JsonWriter writer, string name, Matrix3 matrix)
        {
            var array = matrix.GetArray();
            writer.WriteArrayProperty(name, array);
        }

        public static void WriteMatrix4dProperty(this Utf8JsonWriter writer, string name, Matrix4 matrix)
        {
            var array = matrix.Elements;
            writer.WriteArrayProperty(name, array);
        }

        public static void WriteTransform3dProperty(this Utf8JsonWriter writer, string name, Transform3d transform)
        {
            writer.WritePropertyName(name);
            writer.WriteStartObject();
            writer.WriteVector3dProperty(nameof(transform.Origin), transform.Origin);
            writer.WriteVector3dProperty(nameof(transform.Position), transform.Position);
            writer.WriteEulerProperty(nameof(transform.Euler), transform.Euler);
            writer.WriteVector3dProperty(nameof(transform.Scales), transform.Scales);
            writer.WriteMatrix4dProperty(nameof(transform.Matrix), transform.Matrix);
            writer.WriteEndObject();
        }

        public static void WriteObjectProperty(this Utf8JsonWriter writer, string name, object value, JsonSerializerOptions options)
        {
            writer.WritePropertyName(name);
            JsonSerializer.Serialize(writer, value, options);
        }
        public static void WriteArrayProperty(this Utf8JsonWriter writer, string name, Array array)
        {
            writer.WritePropertyName(name);
            writer.WriteStartArray();
            foreach (var item in array)
            {
                writer.WriteNumberValue((decimal)((double)item));
            }
            writer.WriteEndArray();
        }
        public static void WriteCollectionProperty<T>(this Utf8JsonWriter writer, string name, ICollection<T> collection, JsonSerializerOptions options, Action<Utf8JsonWriter, T> cwriter = null)
        {
            if (collection == null || collection.Count == 0) return;
            writer.WritePropertyName(name);
            if (cwriter == null)
            {
                JsonSerializer.Serialize(writer, collection, options);
            }
            else
            {
                writer.WriteStartArray();
                foreach (T item in collection)
                {
                    cwriter(writer, item);
                }
                writer.WriteEndArray();
            }
        }

        public static void WriteDictionaryProperty<K>(this Utf8JsonWriter writer, string name, IDictionary<string, K> dictionary, JsonSerializerOptions options, Action<Utf8JsonWriter, K> cwriter = null)
        {
            if (dictionary == null || dictionary.Count == 0) return;
            writer.WritePropertyName(name);
            if (cwriter == null)
            {
                JsonSerializer.Serialize(writer, dictionary, options);
            }
            else
            {
                writer.WriteStartObject();
                foreach (var item in dictionary)
                {
                    writer.WritePropertyName(item.Key);
                    cwriter(writer, item.Value);
                }
                writer.WriteEndObject();
            }
        }

        public static void WriteVector2dProperty(this Utf8JsonWriter writer, string name, Vector2 vec)
        {
            writer.WritePropertyName(name);
            writer.WriteStartArray();
            writer.WriteNumberValue(vec.X);
            writer.WriteNumberValue(vec.Y);
            writer.WriteEndArray();
        }
        public static void WriteVector3dProperty(this Utf8JsonWriter writer, string name, Vector3 vec)
        {
            writer.WritePropertyName(name);
            writer.WriteStartArray();
            writer.WriteNumberValue(vec.X);
            writer.WriteNumberValue(vec.Y);
            writer.WriteNumberValue(vec.Z);
            writer.WriteEndArray();
        }
        public static void WriteQuaternionProperty(this Utf8JsonWriter writer, string name, Quaternion quaternion)
        {
            writer.WritePropertyName(name);
            writer.WriteStartArray();
            writer.WriteNumberValue(quaternion.X);
            writer.WriteNumberValue(quaternion.Y);
            writer.WriteNumberValue(quaternion.Z);
            writer.WriteNumberValue(quaternion.W);
            writer.WriteEndArray();
        }
        public static void WriteEulerProperty(this Utf8JsonWriter writer, string name, Euler euler)
        {
            writer.WritePropertyName(name);
            writer.WriteStartArray();
            writer.WriteNumberValue(euler.X);
            writer.WriteNumberValue(euler.Y);
            writer.WriteNumberValue(euler.Z);
            writer.WriteNumberValue((int)euler.Order);
            writer.WriteEndArray();
        }

        public static void WriteCurve2dObject(this Utf8JsonWriter writer,Curve2d curve, JsonSerializerOptions soptions)
        {
            writer.WriteStartObject();
            writer.WriteNumberProperty(nameof(curve.Type), (int)curve.Type);
            Curve2dUtils.WriteProperties(writer, curve, soptions);
            writer.WriteEndObject();
        }
        public static void WriteElementObject(this Utf8JsonWriter writer, LcElement element, JsonSerializerOptions soptions)
        {
            writer.WriteStartObject();
            element.WriteBaseProperties(writer, soptions);
            element.WriteProperties(writer, soptions);
            writer.WriteEndObject();

        }
        public static void WriteElementSetProperty(this Utf8JsonWriter writer, string name, ElementSpace elementSet, JsonSerializerOptions soptions)
        {
            writer.WritePropertyName(name);
            writer.WriteStartArray();
            foreach (LcElement ele in elementSet.Elements)
            {
                writer.WriteElementObject(ele, soptions);
            }
            writer.WriteEndArray();
        }

        public static void WriteElementSetProperty<T>(this Utf8JsonWriter writer, string name, List<T> elements, JsonSerializerOptions soptions) where T : LcElement
        {
            writer.WritePropertyName(name);
            writer.WriteStartArray();
            foreach (LcElement ele in elements)
            {
                writer.WriteElementObject(ele, soptions);
            }
            writer.WriteEndArray();
        }

        public static void WriteElementSetProperty<T>(this Utf8JsonWriter writer, string name, Dictionary<long, T> elementDic, JsonSerializerOptions soptions) where T : LcElement
        {
            writer.WritePropertyName(name);
            writer.WriteStartObject();
            foreach (var kvp in elementDic)
            {
                var ele = kvp;
                writer.WritePropertyName(kvp.Key.ToString());
                writer.WriteElementObject(ele.Value, soptions);
            }
            writer.WriteEndObject();
        }

        public static void WriteComponentObject(this Utf8JsonWriter writer, LcComponentDefinition component, JsonSerializerOptions soptions)
        {
            writer.WriteStartObject();
            writer.WriteStringProperty(nameof(component.Uuid), component.Uuid);
            writer.WriteStringProperty(nameof(component.Name), component.Name);
            writer.WriteStringProperty(nameof(component.DisplayName), component.DisplayName);
            writer.WriteStringProperty(nameof(component.Category), component.Category);
            writer.WriteStringProperty(nameof(component.SubCategory), component.SubCategory);
            writer.WriteStringProperty(nameof(component.Description), component.Description);

            writer.WriteEndObject();
        }
        //public static void WriteComponentShape2dObject(this Utf8JsonWriter writer, Curve2dCreator shape, JsonSerializerOptions soptions)
        //{
        //    writer.WriteStartObject();
        //    writer.WriteStringProperty(nameof(shape.Category), shape.Category);
        //    writer.WriteStringProperty(nameof(shape.SubCategory), shape.SubCategory);
        //    writer.WriteStringProperty(nameof(shape.Name), shape.Name);
        //    writer.WriteStringProperty(nameof(shape.DisplayName), shape.DisplayName);
        //    writer.WriteStringProperty(nameof(shape.Description), shape.Description);

        //    writer.WriteEndObject();
        //}

        public static void WriteBlockObject(this Utf8JsonWriter writer, LcBlock block, JsonSerializerOptions soptions)
        {
            writer.WriteStartObject();
            writer.WriteNumberProperty(nameof(block.Id), block.Id);
            writer.WriteStringProperty(nameof(block.Name), block.Name);
            writer.WriteVector2dProperty(nameof(block.BasePoint), block.BasePoint);

            if (!string.IsNullOrEmpty(block.Description))
                writer.WriteStringProperty(nameof(block.Description), block.Description);
            if (block.AllowAttribute)
                writer.WriteBoolProperty(nameof(block.AllowAttribute), block.AllowAttribute);

            writer.WriteElementSetProperty(nameof(block.Elements), block, soptions);
            writer.WriteEndObject();
        }

        public static void WriteBuildingObject(this Utf8JsonWriter writer, LcBuilding building, JsonSerializerOptions soptions)
        {
            writer.WriteStartObject();
            writer.WriteNumberProperty(nameof(building.Id), building.Id);
            writer.WriteStringProperty(nameof(building.Name), building.Name);

            writer.WriteCollectionProperty(nameof(building.Levels), building.Levels, null, (w, lvl) => w.WriteLevelObject(lvl, soptions));

            writer.WriteEndObject();
        }

        public static void WriteDrawingFrameObject(this Utf8JsonWriter writer, LcDrawingFrame drawingFrame, JsonSerializerOptions soptions)
        {
            writer.WriteStartObject();
            writer.WriteNumberProperty(nameof(drawingFrame.Id), drawingFrame.Id);
            writer.WriteStringProperty(nameof(drawingFrame.Name), drawingFrame.Name);
            writer.WriteVector2dProperty(nameof(drawingFrame.BasePoint), drawingFrame.BasePoint);

            if (!string.IsNullOrEmpty(drawingFrame.Description))
                writer.WriteStringProperty(nameof(drawingFrame.Description), drawingFrame.Description);
            if (drawingFrame.AllowAttribute)
                writer.WriteBoolProperty(nameof(drawingFrame.AllowAttribute), drawingFrame.AllowAttribute);

            writer.WriteElementSetProperty(nameof(drawingFrame.Elements), drawingFrame, soptions);
            writer.WriteEndObject();
        }

        public static void WriteLevelObject(this Utf8JsonWriter writer, LcLevel level, JsonSerializerOptions soptions)
        {

            writer.WriteStartObject();
            writer.WriteIdProperty(nameof(level.Id), level.Id);
            writer.WriteStringProperty(nameof(level.Name), level.Name);
            writer.WriteNumberProperty(nameof(level.Elevation), level.Elevation);
            writer.WriteNumberProperty(nameof(level.S_Elevation), level.S_Elevation);
            writer.WriteNumberProperty(nameof(level.Height), level.Height);
            writer.WriteNumberProperty(nameof(level.S_Height), level.S_Height);

            writer.WriteNumberProperty(nameof(level.Type), (int)level.Type);
            writer.WriteNumberProperty(nameof(level.Index), (int)level.Index);

            writer.WriteCollectionProperty(nameof(level.Drawings), level.Drawings.Select(P => P.Id).ToList(), soptions);

            writer.WriteEndObject();
        }

  
    }

    public static class JsonElementExt
    {
        public static bool NullOrUndefined(this ref JsonElement jele)
        {
            return (jele.ValueKind == JsonValueKind.Null || jele.ValueKind == JsonValueKind.Undefined);
        }
        public static string ReadStringProperty(this ref JsonElement jele, string name, bool required = false)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (required && !exist) throw new Exception("errorformat");
            if (!exist || prop.NullOrUndefined()) return default;
            return prop.GetString();
        }
        public static bool? ReadBoolProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;
            return prop.GetBoolean();
        }
        public static int ReadIntProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;
            return prop.GetInt32();
        }
        public static double ReadDoubleProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;
            return prop.GetDouble();
        }
        public static long ReadIdProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;
            return prop.GetInt64();
        }

        public static Matrix3 ReadMatrix3dProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var data = new double[9];
            var arr = prop.EnumerateArray().ToArray();
            for (var i = 0; i < arr.Length; i++)
            {
                data[i] = arr[i].GetDouble();
            }
            return new Matrix3().FromArray(data);
        }

        public static Matrix4 ReadMatrix4dProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var data = new double[16];
            var arr = prop.EnumerateArray().ToArray();
            for (var i = 0; i < arr.Length; i++)
            {
                data[i] = arr[i].GetDouble();
            }
            return new Matrix4().FromArray(data);
        }

        public static Transform3d ReadTransform3dProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var trans = new Transform3d();
            trans.Origin.Copy(prop.ReadVector3dProperty(nameof(trans.Origin)));
            trans.Position.Copy(prop.ReadVector3dProperty(nameof(trans.Position)));
            trans.Euler.Copy(prop.ReadEulerProperty(nameof(trans.Euler)));
            trans.Scales.Copy(prop.ReadVector3dProperty(nameof(trans.Scales)));
            trans.Matrix.Copy(prop.ReadMatrix4dProperty(nameof(trans.Matrix)));
            return trans;
        }

        public static T ReadObjectProperty<T>(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            return JsonSerializer.Deserialize<T>(prop);
        }
        public static Curve2d ReadCurve2dProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            return prop.ReadCurve2dObject();
        }
        public static List<Curve2d> ReadCurve2dListProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var list = new List<Curve2d>();
            var arr = prop.EnumerateArray().ToArray();
            for(var i=0; i<arr.Length; i++)
            {
                var item = arr[i];
                var curve = item.ReadCurve2dObject();
                list.Add(curve);
            }
            return list;
        }
        public static Curve2d ReadCurve2dObject(this ref JsonElement jele)
        {
            Curve2d curve;
            var exist = jele.TryGetProperty(nameof(curve.Type), out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var curveType = (Curve2dType)(prop.GetInt32());
            curve = Curve2dUtils.Create(curveType);
            Curve2dUtils.ReadProperties(ref jele, curve);
            return curve;

        }
        public static Vector2 ReadVector2dProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var arr = prop.EnumerateArray().ToArray(); 
            var x = arr[0].GetDouble();
            var y = arr[1].GetDouble();
            return new Vector2(x, y);
        }
        public static Vector3 ReadVector3dProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var arr = prop.EnumerateArray().ToArray();
            var x = arr[0].GetDouble();
            var y = arr[1].GetDouble();
            var z = arr[2].GetDouble();
            return new Vector3(x, y, z);
        }

        public static Euler ReadEulerProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var arr = prop.EnumerateArray().ToArray();
            var x = arr[0].GetDouble();
            var y = arr[1].GetDouble();
            var z = arr[2].GetDouble();
            var order = (Euler.RotationOrders)arr[3].GetInt32();
            return new Euler(x, y, z, order);
        }

        public static Quaternion ReadQuaternionProperty(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var arr = prop.EnumerateArray().ToArray();
            var x = arr[0].GetDouble();
            var y = arr[1].GetDouble();
            var z = arr[2].GetDouble();
            var w = arr[3].GetDouble();
            return new Quaternion(x, y, z, w);
        }
        public static T ReadCollectionProperty<T, K>(this ref JsonElement jele, string name, LcDocument doc) where T : ICollection<K>, new()
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var ktype = typeof(K);
            var eleType = typeof(ElementType);
            var blkType = typeof(LcBlock);
            var bdType = typeof(LcBuilding);
            var objType = typeof(LcObject);

            var arr = prop.EnumerateArray().ToArray();
            var tobj = new T();
            for (var i = 0; i < arr.Length; i++)
            {
                var item = arr[i];
                if (ktype.Equals(eleType))
                {
                    var kobj = JsonSerializer.Deserialize<K>(item);
                    tobj.Add(kobj);
                }
                else if (ktype.Equals(blkType))
                {
                    var blk = (object)item.ReadBlockObject(doc);
                    tobj.Add((K)blk);
                }
                else if (ktype.Equals(bdType))
                {
                    var bd = (object)item.ReadBuildingObject(doc);
                    tobj.Add((K)bd);
                }
                else if (ktype.IsSubclassOf(objType))
                {
                    var kobj = (K)JsonSerializer.Deserialize<K>(item);
                    (kobj as LcObject).Document = doc;
                    tobj.Add(kobj);
                }
            }
            return tobj;
        }
        public static IList<T> ReadListProperty<T>(this ref JsonElement jele, string name)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var list = new List<T>();
            var arr = prop.EnumerateArray().ToArray();
            for (var i = 0; i < arr.Length; i++)
            {
                var item = arr[i];
                var tobj = JsonSerializer.Deserialize<T>(item);
                list.Add(tobj);
            }
            return list;
        }
        public static LcElement ReadElementObject(this ref JsonElement jele, LcDocument doc)
        {
            var typeName = jele.GetProperty("TypeName").GetString();
            var baseType = jele.GetProperty("BaseType").GetString();
            LcElement element;
            if (baseType==nameof(LcComponentInstance))
            {
                var comp = ComponentManager.GetCptDef(jele.ReadStringProperty("ComponentId"));
                element = doc.CreateElement(typeName, baseType, comp );
            }
            else
            {
                 element = doc.CreateElement(typeName, baseType);
            }
            element.ReadBaseProperties(ref jele);
            element.ReadProperties(ref jele);
            //// ele.WriteExtProperties(writer, soptions);

            return element;

        }
        public static ElementCollection ReadElementSetProperty(this ref JsonElement jele, string name, LcDocument doc)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var arr = prop.EnumerateArray().ToArray();
            var eleSet = new ElementCollection();
            for (var i = 0; i < arr.Length; i++)
            {
                var ele = arr[i].ReadElementObject(doc);
                eleSet.Add(ele);
            }
            return eleSet;
        }

        public static LcBlock ReadBlockObject(this ref JsonElement jele, LcDocument doc)
        {
            var block = doc.CreateObject<LcBlock>();
            block.Id = jele.ReadIdProperty(nameof(block.Id));
            block.Name = jele.ReadStringProperty(nameof(block.Name));
            block.BasePoint = jele.ReadVector2dProperty(nameof(block.BasePoint));

            if (jele.TryGetProperty(nameof(block.Description), out JsonElement descrProp))
                block.Description = descrProp.GetString();

            if (jele.TryGetProperty(nameof(block.AllowAttribute), out JsonElement allowAttrProp))
                block.AllowAttribute = allowAttrProp.GetBoolean();

            block.Elements = jele.ReadElementSetProperty(nameof(block.Elements), doc);
            return block;
        }

        //public static void WriteDrawingFrameObject(this ref JsonElement jele, LcDocument doc)
        //{
        //    writer.WriteStartObject();
        //    writer.WriteNumberProperty(nameof(block.Id), block.Id);
        //    writer.WriteStringProperty(nameof(block.Name), block.Name);
        //    writer.WriteVector2dProperty(nameof(block.BasePoint), block.BasePoint);

        //    if (!string.IsNullOrEmpty(block.Description))
        //        writer.WriteStringProperty(nameof(block.Description), block.Description);
        //    if (block.AllowAttribute)
        //        writer.WriteBoolProperty(nameof(block.AllowAttribute), block.AllowAttribute);

        //    writer.WriteElementSetProperty(nameof(block.Elements), block, soptions);
        //    writer.WriteEndObject();
        //}

        public static LcBuilding ReadBuildingObject(this ref JsonElement jele, LcDocument doc)
        {
            var building = doc.CreateObject<LcBuilding>();
            building.Id = jele.ReadIdProperty(nameof(building.Id));
            building.Name = jele.ReadStringProperty(nameof(building.Name));
            building.Levels = jele.ReadLevelSetProperty(nameof(building.Levels), doc);
            return building;
        }


        public static LcLevel ReadLevelObject(this ref JsonElement jele, LcDocument doc)
        {
            var level = doc.CreateObject<LcLevel>();
            level.Id = jele.ReadIdProperty(nameof(level.Id));
            level.Name = jele.ReadStringProperty(nameof(level.Name));
            level.Elevation = jele.ReadDoubleProperty(nameof(level.Elevation));
            level.S_Elevation = jele.ReadDoubleProperty(nameof(level.S_Elevation));
            level.Height = jele.ReadDoubleProperty(nameof(level.Height));
            level.S_Height = jele.ReadDoubleProperty(nameof(level.S_Height));
            if (jele.TryGetProperty(nameof(level.Type), out JsonElement prop))
            {
                level.Type = (LcLevelType)prop.GetInt32();
            }

            level.Index = jele.ReadIntProperty(nameof(level.Index));
            if (jele.TryGetProperty("Drawings", out JsonElement drawingEle))
            {
                var ids = jele.ReadListProperty<long>(nameof(level.Drawings));
                level.Drawings = new List<LcDrawing>();
                foreach (var id in ids)
                {
                    var drawing = new LcDrawing() { Id = id }; //doc.ModelSpace.Elements.FirstOrDefault(d => d.Id == id) as LcDrawing;
                    if (drawing != null)
                    {
                        level.Drawings.Add(drawing);
                    }
                }
            }

            return level;
        }
        public static LcLevelCollection ReadLevelSetProperty(this ref JsonElement jele, string name, LcDocument doc)
        {
            var exist = jele.TryGetProperty(name, out JsonElement prop);
            if (!exist || prop.NullOrUndefined()) return default;

            var arr = prop.EnumerateArray().ToArray();
            var levelSet = new LcLevelCollection();
            for (var i = 0; i < arr.Length; i++)
            {
                var level = arr[i].ReadLevelObject(doc);
                levelSet.Add(level);
            }
            return levelSet;
        }

        public static void ReadAxisGridObject(this ref JsonElement jele, LcDocument doc)
        {
            //writer.WriteStartObject();
            //#region Block
            //writer.WriteNumberProperty(nameof(axis.Id), axis.Id);
            //writer.WriteStringProperty(nameof(axis.Name), axis.Name);
            //writer.WriteVector2dProperty(nameof(axis.BasePoint), axis.BasePoint);

            //if (!string.IsNullOrEmpty(axis.Description))
            //    writer.WriteStringProperty(nameof(axis.Description), axis.Description);
            //if (axis.AllowAttribute)
            //    writer.WriteBoolProperty(nameof(axis.AllowAttribute), axis.AllowAttribute);

            //writer.WriteElementSetProperty(nameof(axis.Elements), axis, soptions);
            //#endregion

            //writer.WriteStringProperty(nameof(axis.StyleName), axis.StyleName);
            //writer.WriteStringProperty(nameof(axis.RatioName), axis.RatioName);
            ////writer.WriteElementSetProperty(nameof(axis.axisLines), axis.axisLines)

            //writer.WriteEndObject();
        }
    }
    //public class ElementStyleConverter : JsonConverter<ElementStyle>
    //{
    //    public override ElementStyle? Read(JsonElement jele, Type typeToConvert, JsonSerializerOptions options)
    //    {
    //        var str = jele.GetString();
    //        return ElementStyle.Parse(str);
    //    }

    //    public override void Write(Utf8JsonWriter writer, ElementStyle value, JsonSerializerOptions options)
    //    {
    //        writer.WriteStringValue(value.ToString());
    //    }
    //}

    public class Vector2dConverter : JsonConverter<Vector2>
    {

        public override Vector2 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            reader.Read();
            var x = reader.GetDouble();

            reader.Read();
            var y = reader.GetDouble();

            reader.Read();
            return new Vector2(x, y);
        }

        public override void Write(Utf8JsonWriter writer, Vector2 value, JsonSerializerOptions options)
        {
            writer.WriteStartArray();
            writer.WriteNumberValue(value.X);
            writer.WriteNumberValue(value.Y);
            writer.WriteEndArray();
        }
    }
    //public class DoubleConverter : JsonConverter<double>
    //{
    //    public override double Read(JsonElement jele, Type typeToConvert, JsonSerializerOptions options)
    //    {
    //        var str = jele.GetString();
    //        return double.Parse(str);
    //    }

    //    public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    //    {
    //        throw new NotImplementedException();
    //    }

    //    public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options)
    //    {
    //        writer.WriteStringValue(value.ToString("0.00"));
    //    }
    //}
}
